package com.gopay.common.user.manager.impl;

import com.gopay.common.constants.proccode.ProcCodeEnum;
import com.gopay.common.constants.trans.CustCategory;
import com.gopay.common.constants.trans.CustChannelNum;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.domain.UserInfo;
import com.gopay.common.domain.cust.CustPersonInfo;
import com.gopay.common.domain.user.identify.PersIdUsedQuota;
import com.gopay.common.domain.user.identify.PersIdUsedQuotaLog;
import com.gopay.common.domain.user.identify.RcAcctPayLimit;
import com.gopay.common.domain.user.identify.RcPayVerifyLimit;
import com.gopay.common.user.dao.*;
import com.gopay.common.user.manager.PersonIdentifyManager;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;


@Service("personIdentifyManager")
public class PersonIdentifyManagerImpl implements PersonIdentifyManager{

	protected final static Log logger = LogFactory.getLog(PersonIdentifyManagerImpl.class);
			
    @Resource(name = "userInfoQueryDao")
    private UserInfoQueryDAO userInfoQueryDao;
    
    @Resource(name = "custPersonInfoQueryDao")
    private CustPersonInfoQueryDAO custPersonInfoQueryDao;
    
    @Resource(name = "personIdentifyDAO")
    private PersonIdentifyDAO personIdentifyDao;
    
    @Resource(name = "rcPayVerifyLimitDao")
    private RcPayVerifyLimitDAO rcPayVerifyLimitDao;
    
    @Resource(name = "persCertChannelDtlDao")
    private PersCertChannelDtlDao persCertChannelDtlDao;
    
    @Resource(name = "rcAcctPayLimitDao")
    private RcAcctPayLimitDao rcAcctPayLimitDao;
    
    @Resource(name = "persIdUsedQuotaLogDAO")
    private PersIdUsedQuotaLogDAO persIdUsedQuotaLogDAO;

    @Resource(name = "personIdentifyDAO")
    private PersonIdentifyDAO personIdentifyDAO;

	/**
	 * 支付方式额度校验及三类账户额度校验
	 */
    @Override
    public String getIdentityLimitCheck (String userId, BigDecimal orderAmt, String payType, String operation) {
        //1.通过userid查询用户的信息
        UserInfo userInfo=userInfoQueryDao.getUserInfoByUserId(userId);
        //2.通过用户的custid查询cust表中的身份证号
        CustPersonInfo custInfo=custPersonInfoQueryDao.getByCustId(userInfo.getCustId());
        //3.通过身份证号查询身份已用额度信息
        PersIdUsedQuota persIdUsedQuota=personIdentifyDao.getIdentityInfo(custInfo.getCertNo());
        if(null == persIdUsedQuota){
        	logger.error("该客户的客户ID是"+userInfo.getCustId()+",它的pers_id_used_quota表中没记录");
        	return ProcCodeEnum.PROC_CODE_100E6001.getCode();
        }
        
        //4.通过支付方式来查询单日额度
        RcPayVerifyLimit rcPayVerifyLimit=rcPayVerifyLimitDao.findByCode(payType);
        if(null == rcPayVerifyLimit){
        	logger.error("该客户的客户ID是"+userInfo.getCustId()+",它的payType是"+payType);
        	return ProcCodeEnum.PROC_CODE_100E6001.getCode();
        }
               
        //5.单日累计额度
        BigDecimal totayOrderAmt=personIdentifyDao.findMainorderAmt(userInfo.getCustId());
        
        //6.通过custId查询出该客户是几类账号
        String custCategory=CustChannelNum.custType(persCertChannelDtlDao.findSuccessCertChannelCountsByCustId(userInfo.getCustId()));
        
        //7.通过客户分类查询终身与年累计额度
        RcAcctPayLimit rcAcctPayLimit=rcAcctPayLimitDao.findByAcctType(custCategory);
        if(null == rcAcctPayLimit){
        	logger.error("该客户的客户ID是"+userInfo.getCustId()+",它的账户类型是"+custCategory);
        	return ProcCodeEnum.PROC_CODE_100E6001.getCode();
        }
        
        if(CustCategory.one.value.equals(custCategory)){//一类账户
        	logger.error("totayOrderAmt "+totayOrderAmt+"|orderAmt "+orderAmt+"|custCategory "+custCategory+"|payType "+payType);
        	logger.error("rcAcctPayLimit "+ToStringBuilder.reflectionToString(rcAcctPayLimit));
            //判断是提现的话不进行单日额度校验
        	if((totayOrderAmt.add(orderAmt)).compareTo(rcPayVerifyLimit.getTodayTotalLimit())==1 
        			&& !(IntTxnCd._00800.value.equals(operation))){
                    return ProcCodeEnum.PROC_CODE_200E5011.getCode();//风控支付方式超额
            }else{
            	if(IntTxnCd._01615.value.equals(operation)){//增加天溢盈购买交易对一类账户的校验 modify by tangyang at20170307
            		return ProcCodeEnum.PROC_CODE_100E9434.getCode();//非三类账户不可购买天溢盈
            	}
                if(IntTxnCd._02019.value.equals(operation)){//增加基金活期宝转入对一类账户的校验 modify by jianghoupeng at 20171218
                    return ProcCodeEnum.PROC_CODE_100E9434.getCode();//非三类账户不可购买 基金
                }
                if((persIdUsedQuota.getAllUsedQuota().add(orderAmt)).compareTo(rcAcctPayLimit.getAcctLimit())==1){
                    return ProcCodeEnum.PROC_CODE_200E5010.getCode();//三类账户超额
                }else{
                	return ProcCodeEnum.PROC_CODE_200S1000.getCode();
                }
            }
        }else if(CustCategory.two.value.equals(custCategory)){ //二类账户
        	//判断是提现的话不进行单日额度校验
            if((totayOrderAmt.add(orderAmt)).compareTo(rcPayVerifyLimit.getTodayTotalLimit())==1 
            		&& !(IntTxnCd._00800.value.equals(operation))){
                    return ProcCodeEnum.PROC_CODE_200E5011.getCode();//风控支付方式超额
            }else{
            	if(IntTxnCd._01615.value.equals(operation)){//增加天溢盈购买交易对二类账户的校验 modify by tangyang at20170307
            		return ProcCodeEnum.PROC_CODE_100E9434.getCode();//非三类账户不可购买天溢盈
            	}
                if(IntTxnCd._02019.value.equals(operation)){//增加基金活期宝转入对一类账户的校验 modify by jianghoupeng at 20171218
                    return ProcCodeEnum.PROC_CODE_100E9434.getCode();//非三类账户不可购买 基金
                }
                if(!(IntTxnCd._00800.value.equals(operation)) 
                		&& (persIdUsedQuota.getYearUsedQuota().add(orderAmt)).compareTo(rcAcctPayLimit.getAcctLimit())==1){
                    return ProcCodeEnum.PROC_CODE_200E5010.getCode();//三类账户超额
                }else{
                    return ProcCodeEnum.PROC_CODE_200S1000.getCode();
                } 
            }
        }else if(CustCategory.three.value.equals(custCategory)){ //三类账户
        	//判断是提现的话不进行单日额度校验
            if((totayOrderAmt.add(orderAmt)).compareTo(rcPayVerifyLimit.getTodayTotalLimit())==1 
            		&& !(IntTxnCd._00800.value.equals(operation))){
                    return ProcCodeEnum.PROC_CODE_200E5011.getCode();//风控支付方式超额
            }else{
                if(!(IntTxnCd._00800.value.equals(operation)) && (persIdUsedQuota.getYearUsedQuota().add(orderAmt)).compareTo(rcAcctPayLimit.getAcctLimit())==1){
                    return ProcCodeEnum.PROC_CODE_200E5010.getCode();//三类账户超额
                }else{
                    return ProcCodeEnum.PROC_CODE_200S1000.getCode();
                } 
            }
        }else{
        	logger.error("未获取到该账户的三类账户级别" + userInfo.getCustId());
        	return ProcCodeEnum.PROC_CODE_100E6001.getCode();
        }
    }
    
   
   @Override
   @Transactional
   public void updateIndentifyInfo(String userId,BigDecimal orderAmt,String operation,String gopayOrderId){
       BigDecimal quotaBeforeAmt=new BigDecimal("0.00");//修改前金额
       BigDecimal quotaAfterAmt=new BigDecimal("0.00");//修改后金额
       
       //1.通过userid查询用户的信息
       UserInfo userInfo=userInfoQueryDao.getUserInfoByUserId(userId);

       //add by zhaojt
       PersIdUsedQuotaLog log = persIdUsedQuotaLogDAO.findByOrderId(gopayOrderId);
       if(log != null){
            logger.info("检索到已用额度日志表数据, 不在重复更新额度! ");
            return;
       }

       //2.通过用户的custid查询cust表中的身份证号
       CustPersonInfo custInfo=custPersonInfoQueryDao.getByCustId(userInfo.getCustId());
       
       //3.通过身份证号查询身份已用额度信息
       PersIdUsedQuota persIdUsedQuota=personIdentifyDao.getIdentityInfo(custInfo.getCertNo());
       
       //4.通过custId查询出该客户是几类账号
       String custCategory=CustChannelNum.custType(persCertChannelDtlDao.findSuccessCertChannelCountsByCustId(userInfo.getCustId()));
       
       persIdUsedQuota.setLastUpdUserId(userId);//最新更新用户id
       if(CustCategory.one.value.equals(custCategory)){//一类账户
           quotaBeforeAmt=persIdUsedQuota.getAllUsedQuota();//修改前金额
           if(IntTxnCd._00800.value.equals(operation)){//一类账户提现
               persIdUsedQuota.setAllUsedQuota(persIdUsedQuota.getAllUsedQuota().add(orderAmt));
           }else{//一类账户非提现
               persIdUsedQuota.setAllUsedQuota(persIdUsedQuota.getAllUsedQuota().add(orderAmt));
               persIdUsedQuota.setYearUsedQuota(persIdUsedQuota.getYearUsedQuota().add(orderAmt));
           }
           quotaAfterAmt=persIdUsedQuota.getAllUsedQuota();//修改后金额
           personIdentifyDao.updateIndentify(persIdUsedQuota);
           
       }else{//二三类账户
           quotaBeforeAmt=persIdUsedQuota.getYearUsedQuota();//修改前金额
           if(!(IntTxnCd._00800.value.equals(operation))){//二三类账户非提现
               persIdUsedQuota.setAllUsedQuota(persIdUsedQuota.getAllUsedQuota().add(orderAmt));
               persIdUsedQuota.setYearUsedQuota(persIdUsedQuota.getYearUsedQuota().add(orderAmt)); 
               personIdentifyDao.updateIndentify(persIdUsedQuota);
           }
           quotaAfterAmt=persIdUsedQuota.getYearUsedQuota();//修改后金额
       }
        
        //插入身份证已用额度日志开始
        PersIdUsedQuotaLog  persIdUsedQuotaLog=new PersIdUsedQuotaLog();
        persIdUsedQuotaLog.setCustId(userInfo.getCustId());//客户id
        persIdUsedQuotaLog.setCertNo(custInfo.getCertNo());//身份证号
        persIdUsedQuotaLog.setGopayIntTxnCd(operation);//国付宝内部交易码
        persIdUsedQuotaLog.setAmt(orderAmt);//订单金额
        persIdUsedQuotaLog.setGopayOrderId(gopayOrderId);//国付宝系统订单号
        persIdUsedQuotaLog.setQuotaBeforeAmt(quotaBeforeAmt);//修改前余额
        persIdUsedQuotaLog.setQuotaAfterAmt(quotaAfterAmt);//修改后余额
        persIdUsedQuotaLog.setAccountType(custCategory);//账户类别 
        persIdUsedQuotaLog.setCreatedOperId(userId);//创建人
        persIdUsedQuotaLog.setCreatedTs(new Date());//创建时间
        persIdUsedQuotaLog.setLastUpdOperId(userId);//最后更新人
        persIdUsedQuotaLog.setLastUpdTs(new Date());//组合更新时间
        if(CustCategory.one.value.equals(custCategory)){//一类账户
            persIdUsedQuotaLogDAO.save(persIdUsedQuotaLog);
        }else{//二三类账号非提现
            if(!(IntTxnCd._00800.value.equals(operation))){
                persIdUsedQuotaLogDAO.save(persIdUsedQuotaLog);
            }
        }
        //插入身份证已用额度日志结束
   }
   
   
   @Override
   @Transactional
   public void detractCashIndentifyInfo(String userId,BigDecimal orderAmt,String gopayOrderId){
	   
	   BigDecimal aduitBeforeAmt=new BigDecimal("0.00");//审核不通过前金额
	   
	   //1.通过userid查询用户的信息
       UserInfo userInfo=userInfoQueryDao.getUserInfoByUserId(userId);
       
       //2.通过custId查询出该客户是几类账号
       String custCategory=CustChannelNum.custType(persCertChannelDtlDao.findSuccessCertChannelCountsByCustId(userInfo.getCustId()));
       if(CustCategory.one.value.equals(custCategory)){//一类账户
    	  //3.通过用户的custid查询cust表中的身份证号
          CustPersonInfo custInfo=custPersonInfoQueryDao.getByCustId(userInfo.getCustId());
    	   	
    	  //4.通过身份证号查询身份已用额度信息
    	  PersIdUsedQuota persIdUsedQuota=personIdentifyDao.getIdentityInfo(custInfo.getCertNo());//身份已用额度
    	  if(null != persIdUsedQuota){
    		aduitBeforeAmt=persIdUsedQuota.getAllUsedQuota();
    		persIdUsedQuota.setAllUsedQuota((persIdUsedQuota.getAllUsedQuota().subtract(orderAmt)));
    	   	persIdUsedQuota.setLastUpdUserId(userId);
    	   	persIdUsedQuota.setLastUpdTs(new Date());
    	   	personIdentifyDao.update(persIdUsedQuota);
    	   	
    	   	//插入身份证已用额度日志开始
    	   	PersIdUsedQuotaLog  persIdUsedQuotaLog=new PersIdUsedQuotaLog();
            persIdUsedQuotaLog.setCustId(userInfo.getCustId());//客户id
            persIdUsedQuotaLog.setCertNo(custInfo.getCertNo());//身份证号
            persIdUsedQuotaLog.setGopayIntTxnCd(IntTxnCd._00800.value);//国付宝内部交易码
            persIdUsedQuotaLog.setAmt((new BigDecimal("0.00").subtract(orderAmt)));//订单金额
            persIdUsedQuotaLog.setGopayOrderId(gopayOrderId);//国付宝系统订单号
            persIdUsedQuotaLog.setQuotaBeforeAmt(aduitBeforeAmt);//修改前余额
            persIdUsedQuotaLog.setQuotaAfterAmt(persIdUsedQuota.getAllUsedQuota());//修改后余额
            persIdUsedQuotaLog.setAccountType(custCategory);//账户类别 
            persIdUsedQuotaLog.setCreatedOperId(userId);//创建人
            persIdUsedQuotaLog.setCreatedTs(new Date());//创建时间
            persIdUsedQuotaLog.setLastUpdOperId(userId);//最后更新人
            persIdUsedQuotaLog.setLastUpdTs(new Date());//组合更新时间
            persIdUsedQuotaLogDAO.save(persIdUsedQuotaLog);
    	   	//插入身份证已用额度日志结束
    	   }
       }      
   }

    @Override
    @Transactional
	public void updateUserQuota(String custId, BigDecimal orderAmt, String gopayOrderId, String intTxnCd) {
		BigDecimal aduitBeforeAmt = new BigDecimal("0.00");//审核不通过前金额
	    //1.通过userid查询用户的信息
		List<UserInfo> users = userInfoQueryDao.getByCustId(custId);
		UserInfo userInfo = new UserInfo(); 
		if( users != null && users.size() > 0 ){
			userInfo = users.get(0);
	    }
		if( userInfo != null ){
			//2.通过custId查询出该客户是几类账号
			String custCategory = CustChannelNum.custType(persCertChannelDtlDao.findSuccessCertChannelCountsByCustId(userInfo.getCustId()));
		  	
			//3.通过用户的custid查询cust表中的身份证号
			CustPersonInfo custInfo = custPersonInfoQueryDao.getByCustId(userInfo.getCustId());
		   	
		  	//4.通过身份证号查询身份已用额度信息
			PersIdUsedQuota persIdUsedQuota = personIdentifyDao.getIdentityInfo(custInfo.getCertNo());//身份已用额度
			if( null != persIdUsedQuota ){
				aduitBeforeAmt = persIdUsedQuota.getAllUsedQuota();
				if(CustCategory.two.value.equals(custCategory) || CustCategory.three.value.equals(custCategory)){
					aduitBeforeAmt = persIdUsedQuota.getYearUsedQuota();
				}
				persIdUsedQuota.setAllUsedQuota((persIdUsedQuota.getAllUsedQuota().subtract(orderAmt)));
				persIdUsedQuota.setYearUsedQuota((persIdUsedQuota.getYearUsedQuota().subtract(orderAmt)));
				persIdUsedQuota.setLastUpdUserId(userInfo.getUserId());
				persIdUsedQuota.setLastUpdTs(new Date());
				personIdentifyDao.update(persIdUsedQuota);
		   	
				BigDecimal aduitAfterAmt = persIdUsedQuota.getAllUsedQuota();
				if(CustCategory.two.value.equals(custCategory) || CustCategory.three.value.equals(custCategory)){
					aduitAfterAmt = persIdUsedQuota.getYearUsedQuota();
				}
			   	//插入身份证已用额度日志开始
				PersIdUsedQuotaLog  persIdUsedQuotaLog = new PersIdUsedQuotaLog();
				persIdUsedQuotaLog.setCustId(userInfo.getCustId());//客户id
				persIdUsedQuotaLog.setCertNo(custInfo.getCertNo());//身份证号
				persIdUsedQuotaLog.setGopayIntTxnCd(intTxnCd);//国付宝内部交易码
				persIdUsedQuotaLog.setAmt((new BigDecimal("0.00").subtract(orderAmt)));//订单金额
				persIdUsedQuotaLog.setGopayOrderId(gopayOrderId);//国付宝系统订单号
				persIdUsedQuotaLog.setQuotaBeforeAmt(aduitBeforeAmt);//修改前余额
				persIdUsedQuotaLog.setQuotaAfterAmt(aduitAfterAmt);//修改后余额
				persIdUsedQuotaLog.setAccountType(custCategory);//账户类别 
				persIdUsedQuotaLog.setCreatedOperId(userInfo.getUserId());//创建人
				persIdUsedQuotaLog.setCreatedTs(new Date());//创建时间
				persIdUsedQuotaLog.setLastUpdOperId(userInfo.getUserId());//最后更新人
				persIdUsedQuotaLog.setLastUpdTs(new Date());//组合更新时间
				persIdUsedQuotaLogDAO.save(persIdUsedQuotaLog);
				//插入身份证已用额度日志结束
			}
		}
	}



	@Override
    @Transactional
    public void rollbackThreeAcct(String orderId, String acctPoint){
        logger.info("回滚三类账户已用额度, orderId = " + orderId);
        List<PersIdUsedQuotaLog> list = persIdUsedQuotaLogDAO.findListByOrderId(orderId);

        //存在日志且未被回滚
        if(list != null && list.size() == 1){
            PersIdUsedQuotaLog log = list.get(0);
            BigDecimal quotaBeforeAmt=new BigDecimal("0.00");//修改前金额
            BigDecimal quotaAfterAmt=new BigDecimal("0.00");//修改后金额

            PersIdUsedQuota persIdUsedQuota = personIdentifyDAO.findByIndentifyNo(log.getCertNo());

            //交易时的账户类别
            String accountType = log.getAccountType();

            //提现,手机转账到银行,手机信用卡还款 ：一阶段账务未成功回滚，一阶段账务成功，console拒绝时回滚。
            //|| IntTxnCd._01605.value.equals(log.getGopayIntTxnCd()) || IntTxnCd._01606.value.equals(log.getGopayIntTxnCd())  钱包自己处理
            if(IntTxnCd._00800.value.equals(log.getGopayIntTxnCd())){
                if(StringUtils.isNotBlank(acctPoint)){
                    logger.info("提现交易记账点不为null，不回滚!");
                    return;
                }
            }

            //一类
            if(CustCategory.one.value.equals(accountType)){
                quotaBeforeAmt=persIdUsedQuota.getAllUsedQuota();//修改前金额
                if(IntTxnCd._00800.value.equals(log.getGopayIntTxnCd())){//一类账户提现
                    persIdUsedQuota.setAllUsedQuota(persIdUsedQuota.getAllUsedQuota().subtract(log.getAmt()));
                }else{//一类账户非提现
                    persIdUsedQuota.setAllUsedQuota(persIdUsedQuota.getAllUsedQuota().subtract(log.getAmt()));
                    persIdUsedQuota.setYearUsedQuota(persIdUsedQuota.getYearUsedQuota().subtract(log.getAmt()));
                }
                quotaAfterAmt=persIdUsedQuota.getAllUsedQuota();//修改后金额
                personIdentifyDAO.updateIndentify(persIdUsedQuota);
                //二三类
            }else{
                quotaBeforeAmt=persIdUsedQuota.getYearUsedQuota();//修改前金额
                if(!(IntTxnCd._00800.value.equals(log.getGopayIntTxnCd()))){//二三类账户非提现
                    persIdUsedQuota.setAllUsedQuota(persIdUsedQuota.getAllUsedQuota().subtract(log.getAmt()));
                    persIdUsedQuota.setYearUsedQuota(persIdUsedQuota.getYearUsedQuota().subtract(log.getAmt()));
                    personIdentifyDAO.updateIndentify(persIdUsedQuota);
                }
                quotaAfterAmt=persIdUsedQuota.getYearUsedQuota();//修改后金额
            }

            //插入身份证已用额度日志开始
            PersIdUsedQuotaLog  persIdUsedQuotaLog=new PersIdUsedQuotaLog();
            persIdUsedQuotaLog.setCustId(log.getCustId());//客户id
            persIdUsedQuotaLog.setCertNo(log.getCertNo());//身份证号
            persIdUsedQuotaLog.setGopayIntTxnCd(log.getGopayIntTxnCd());//国付宝内部交易码
            persIdUsedQuotaLog.setAmt(new BigDecimal(0).subtract(log.getAmt()));//订单金额
            persIdUsedQuotaLog.setGopayOrderId(log.getGopayOrderId());//国付宝系统订单号
            persIdUsedQuotaLog.setQuotaBeforeAmt(quotaBeforeAmt);//修改前余额
            persIdUsedQuotaLog.setQuotaAfterAmt(quotaAfterAmt);//修改后余额
            persIdUsedQuotaLog.setAccountType(log.getAccountType());//账户类别
            persIdUsedQuotaLog.setCreatedOperId(log.getCreatedOperId());//创建人
            persIdUsedQuotaLog.setCreatedTs(new Date());//创建时间
            persIdUsedQuotaLog.setLastUpdOperId(log.getCreatedOperId());//最后更新人
            persIdUsedQuotaLog.setLastUpdTs(new Date());//组合更新时间
            if(CustCategory.one.value.equals(log.getAccountType())){//一类账户
                persIdUsedQuotaLogDAO.save(persIdUsedQuotaLog);
            }else{//二三类账号非提现
                if(!(IntTxnCd._00800.value.equals(log.getAccountType()))){
                    persIdUsedQuotaLogDAO.save(persIdUsedQuotaLog);
                }
            }
        }

    }
}
